package com.amway.qy.util.common;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



public class QyHttpClientUtils {

	private static Logger logger = LoggerFactory.getLogger(QyHttpClientUtils.class);
	
	private static final Charset utf8 = Charset.forName("UTF-8");
	
    private final static DefaultHttpClient getHttpsClient(){
		// 创建默认的httpClient实例
		DefaultHttpClient httpClient = new DefaultHttpClient();
		
		X509TrustManager xtm = new X509TrustManager() { // 创建TrustManager
			public void checkClientTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
			}

			public void checkServerTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
			}

			public X509Certificate[] getAcceptedIssuers() {
				return null;
			}
		};
		
		X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier(){

			public boolean verify(String arg0, SSLSession arg1) {
				return false;
			}

			public void verify(String arg0, SSLSocket arg1) throws IOException {
				
			}

			public void verify(String arg0, X509Certificate arg1) throws SSLException {
				
			}

			public void verify(String arg0, String[] arg1, String[] arg2) throws SSLException {
				
			}
			
		};
			
		SSLContext ctx;
		try {
			
//			ctx = SSLContext.getInstance("SSL", "SunJSSE");
			ctx = SSLContext.getInstance("TLS");
			
			// 使用TrustManager来初始化该上下文，TrustManager只是被SSL的Socket所使用
			ctx.init(null, new TrustManager[] { xtm }, new java.security.SecureRandom());

			// 创建SSLSocketFactory
			SSLSocketFactory socketFactory = new SSLSocketFactory(ctx, hostnameVerifier);

			// 通过SchemeRegistry将SSLSocketFactory注册到我们的HttpClient上
			httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
		} catch (Exception e) {
			
		}

		return httpClient;
	}
        
    public  final static String httpsGet(String url, List<NameValuePair> paramsMap){
    	Map<String, String> headerMap = new HashMap<String, String>();
		headerMap.put("Content-Type", "application/x-www-form-urlencoded; charset=" + utf8.name());
    	return get(url,paramsMap,headerMap);
    }
    
    public  final static String httpsPost(String url, List<NameValuePair> paramsMap,Map<String, String> postDataMap){
    	Map<String, String> headerMap = new HashMap<String, String>();
		headerMap.put("Content-Type", "application/x-www-form-urlencoded; charset=" + utf8.name());

		List<BasicNameValuePair> postData = parseMap2BasicForm(postDataMap);
		
		UrlEncodedFormEntity entity = null;
		try {
			entity = new UrlEncodedFormEntity(postData,utf8.name());
		} catch (UnsupportedEncodingException e) {
			logger.error("Failed to encode the form entity.", e);
			throw new RuntimeException(e);
		}	
		return post(url,paramsMap,headerMap,entity);
    }
    
    /**
	 * HTTPSPOST JSON 改为根据URL的前面几个字母（协议）
	 * @param url
	 * @param paramJson
	 * @param encoding
	 * @return
	 */
	public final static String httpsPostJson(String url,List<NameValuePair> paramsMap,String postDataJson) {
		Map<String, String> headerMap = new HashMap<String, String>();
		headerMap.put("Content-Type", "application/json; charset=" + utf8.name());
		//组装参数
		StringEntity entity = null;
		try {
			entity = new StringEntity(postDataJson, utf8.name());
		} catch (Exception e) {
			logger.error("Failed to encode the JSON entity.", e);
			throw new RuntimeException(e);
		}
		return post( url,paramsMap, headerMap, entity );
	}

	/**
	 * HTTPSPOST JSON 改为根据URL的前面几个字母（协议）
	 * @param url
	 * @param paramJson
	 * @param encoding
	 * @return
	 */
	public final static String httpsPostJson(String url,String postDataJson) {
		Map<String, String> headerMap = new HashMap<String, String>();
		headerMap.put("Content-Type", "application/json; charset=" + utf8.name());
		//组装参数
		StringEntity entity = null;
		try {
			entity = new StringEntity(postDataJson, utf8.name());
		} catch (Exception e) {
			logger.error("Failed to encode the JSON entity.", e);
			throw new RuntimeException(e);
		}
		return post( url,new ArrayList<NameValuePair>(), headerMap, entity );
	}
    
	private final static String get(String url, List<NameValuePair> paramsMap, Map<String, String> headerMap) {
		
		String result = "";
		
		URI uri = null;
		try {
			uri = new URIBuilder(url)
							.addParameters(paramsMap)
							.build();
		} catch (URISyntaxException e) {
			logger.error("Failed to create a legal URI by given url:"+url, e);
		}
		
		// 创建一个httpGet请求
		HttpGet request = new HttpGet(uri);
		
		// 组装header参数
		Set<Entry<String, String>> headerEntries = headerMap.entrySet();
		for (Entry<String, String> entry : headerEntries) {
			request.setHeader(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
		}

		CloseableHttpClient httpClient = null;
		try{
			httpClient = getHttpsClient();
			HttpResponse httpResponse = httpClient.execute(request);
			int statusCode = httpResponse.getStatusLine().getStatusCode();
			if (statusCode == HttpStatus.SC_OK) {
				// 得到客户段响应的实体内容
				result = EntityUtils.toString(httpResponse.getEntity(), utf8.name());
			} else {
				logger.error("URL:" + url + "\tStatusCode:" + statusCode);
			}
		}catch(Exception ex){
			logger.error("", ex);
		}

		return result;
	}
    
	private final static String post(	String url,
										List<NameValuePair> paramsMap,
										Map<String, String> headerMap,
										HttpEntity requestEntity ) {
		String result = "";
		
		URI uri = null;
		try {
			uri = new URIBuilder(url)
							.addParameters(paramsMap)
							.build();
		} catch (URISyntaxException e) {
			logger.error("Failed to create a legal URI by given url:"+url, e);
		}
		
		CloseableHttpClient httpClient = null;
		try {
			// 创建一个httpGet请求
			HttpPost httppost = new HttpPost(uri);

			// 组装header参数
			Set<Entry<String, String>> headerEntries = headerMap.entrySet();
			for (Entry<String, String> entry : headerEntries) {
				httppost.setHeader(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
			}
			
			// 设置参数
			httppost.setEntity(requestEntity);

			logger.info("Post Data to ["+url+"] ");

			httpClient = getHttpsClient();

			HttpResponse httpResponse = httpClient.execute(httppost);
			int statusCode = httpResponse.getStatusLine().getStatusCode();
			
			if (statusCode == HttpStatus.SC_OK) {
				result = EntityUtils.toString(httpResponse.getEntity(),utf8.name());
			}
		} catch (Exception e) {
			String errorInfo=String.format("httpclient post failed:\nUrl=%s\nError=%s",url,e.toString());
			logger.error(errorInfo,e);
		}finally{
			if(httpClient != null){
				try {
					httpClient.close();
				} catch (IOException e) {}
			}
		}

		return result;
	}
	
	/**
	 * 封装MAP格式的参数到BasicNameValuePair中
	 * 
	 * @param paramsMap
	 * @return
	 */
	private static final List<BasicNameValuePair> parseMap2BasicForm(Map<String, String> paramsMap) {
		List<BasicNameValuePair> params =new ArrayList<BasicNameValuePair>();;
		if (paramsMap != null && paramsMap.size() > 0) {
			Iterator<String> it = paramsMap.keySet().iterator();
			
			String keyTmp = null;
			while (it.hasNext()) {
				keyTmp = it.next();
				params.add(new BasicNameValuePair(keyTmp, paramsMap.get(keyTmp)));
			}
		}
		return params;
	}
	
	private static class QyWechatX509TrustManager implements X509TrustManager{

		@Override
		public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
			// TODO Auto-generated method stub
			
		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			// TODO Auto-generated method stub
			return null;
		}

		 
	}

	private static class QyWechatVerifyHostname implements HostnameVerifier {  
		  
	    @Override  
	    public boolean verify(String arg0, SSLSession arg1) {  
	    	return false;  
	    }  
	  
	}  
}
